/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package lc.pkg3b.assembler;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

/**
 *
 * @author KyleSweeney
 */
public class LC3BAssembler {
    
    private static String[] ops = {"ADD","AND","BR","JMP","JSR","JSRR","LDB",
        "LDW","LEA","NOT","RET","RTI","LSHF","RSHFL","RSHFA","STB","STW","TRAP",
        "XOR"};
    private static int IC=0;
    HashMap<String, Byte> labels = new HashMap<String, Byte>();

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        if(args.length < 2){
            System.out.println("Proper usage: java -jar LCS3BAssembler.jar <file>");
        }
        File assemble = new File(args[0]);
        System.out.println("Size of file: "+size(assemble));
        
//        File baseFolder = new File(args[1]).getParentFile();
//        File outfile = new File("main.bin");
//        outfile.createNewFile();
//        
//        ArrayList<Byte> finalAssem = new ArrayList<Byte>();
//        
//        FileWriter out = new FileWriter(outfile);
//        for(Byte b : finalAssem){
//            out.write(b.byteValue());
//        }
//        out.flush();
    }
    
    private static void FillNOP(ArrayList<Byte> assem, int size){
        for(int i =0; i< size ; i++){
            assem.add((byte)0x00);
        }
    }
    
    private static int size(File f) throws FileNotFoundException{
        int currentPC=0;
        Scanner r = new Scanner(f);
        String line ="";
        boolean jumpedBack=false;
        while(r.hasNextLine()){
            line = r.nextLine();
            if(line.contains(".ORIG")){
                int org = Integer.parseInt(line.substring(line.indexOf(".ORIG")+".ORIG".length()+1));
                if(org < currentPC){
                    jumpedBack=true;
                    continue;
                }else{
                    jumpedBack=false;
                }
                currentPC = org;
            }
            if (jumpedBack) {
                continue;
            }
            int commentStart = -1;
            if(line.contains(";")){
                commentStart = line.indexOf(';');
            }
            int instructionStart = -1;
            for(String s: ops){
                if(line.contains(s) ){
                    instructionStart = line.indexOf(s);
                    break;
                }
            }
            if(instructionStart > -0 && (instructionStart < commentStart || commentStart==-1)){
                currentPC+=2;
            }
        }
        
        return currentPC;
    }
    
    private static void insertOps(ArrayList<Byte> finalFile, File f) throws FileNotFoundException{
        Scanner r = new Scanner(f);
        String line ="";
        while(r.hasNextLine()){
            line = r.nextLine();
            
            for(String op : ops){
                if(line.contains(".ORIG")){
                int org = Integer.parseInt(line.substring(line.indexOf(".ORIG")+".ORIG".length()+1));
                IC = org;
            }
                if(line.contains(op)){
                    switch(op){
                        case "ADD":{
                            int start = line.indexOf("ADD")+"ADD".length()+1;
                            int semi = line.indexOf(';');
                            //prevent comments from being bad
                            if(semi < start && semi != -1) continue;
                            String[] args = line.substring(start, (semi > -1 ? semi : line.length())).split(",");
                            if(args.length < 3){
                                System.out.println("Error: too few arguments in ADD statement: line "+IC);
                                System.exit(-1);
                            }
                            int DR = convertRegister(args[0]);
                            int SR1 = convertRegister(args[1]);
                            int SR2 =0;
                            int low=0,high=0;
                            if (!args[2].contains("R")) {
                                SR2 = convertRegister(args[2]);
                                low = (SR2 | (SR1 << 6)) & 0b11111111;
                                high = ((0b00010000) | (DR << 1) | (SR1 >> 2)) & 0b11111111;
                            }
                            else{
                                SR2 = Integer.parseInt(args[2]);
                                high = ((0b00010000) | (DR << 1) | (SR1 >> 2))& 0b11111111;
                                low = ((0b00011111 & SR2) | (1 << 5) | (SR1 << 6))& 0b11111111;
                            }
                            finalFile.add(IC++, (byte)low);
                            finalFile.add(IC++, (byte)high);
                        }
                        case "AND":{
                            
                        }
                    }
                }
            } 
        }
    }
    
    public static int convertRegister(String reg){
        int r = reg.indexOf("R");
        int ret = Integer.parseInt(reg.substring(r+1));
        return ret;
    }
}
